package mop.model.user;
import java.util.LinkedList;
import java.util.List;

import mop.exception.IllegalDescriptionException;
import mop.exception.IllegalDuplicationException;
import mop.model.AbstractModel;
import mop.model.AbstractModelWithDescription;
import mop.model.DataBase;
import mop.model.ModelInterface;
import mop.model.task.Task;
import mop.security.acl.RoleInterface;

/**
 * Class for User
 * 
 * @invar name is valid
 * 	|hasValidName()
 * 
 * @author	MOP Team 7
 */
public class User extends AbstractModelWithDescription implements UserInterface, RoleInterface
{
	
	/**
	 * Constructor for User class
	 * 
	 * @param ut the userTYpe
	 * @param name the name of the User
	 * @param db the database reference
	 * 
	 * @post usertype is set to ut
	 * @post tasklist is created as empty list
	 * @effect this User is added to database
	 * @effect name is set as description
	 * 
	 * @throws IllegalDescriptionException
	 * 		| @see AbstractDescriptionModel
	 * @throws IllegalDuplicationException 
	 * 		| user might be duplicate
	 */
	public User(UserType ut,String name,DataBase<User> db) throws IllegalDescriptionException, IllegalDuplicationException
	{
		super(name);
		db.add(this);
		this.tasks = new LinkedList<Task>();
		this.usertype = ut;
	}
	
	/***************************************************************************
	 * 						Model interface
	 ***************************************************************************/
	
	/**
	 * @see ModelInterface#getId()
	 */
	public String getId() 
	{
		return toString();
	}
	
	/**
	 * get a reference to the interface
	 * @return this
	 */
	public UserInterface getInterface()
	{
		return this;
	}
	
		
	/***************************************************************************
	 * 						Tasks
	 ***************************************************************************/
	
	/**
	 * Inspector for the task list
	 * 
	 * @return A copy of that list
	 */
	public List<Task> getTasks()
	{
		List<Task> temporary = new LinkedList<Task>();
		for(Task temp : this.tasks)
		{
			temporary.add(temp);
		}
		return temporary;
	}
	
	/**
	 * Mutator for Task List, inserts a new Task
	 * @param task 	Task to add
	 * @throws IllegalDuplicationException 
	 * @effect task t is added to this.tasks
	 * 	|this.tasks.add(t);
	 */
	public void addTask(Task t) throws IllegalDuplicationException
	{
		if(!tasks.contains(t))
			this.tasks.add(t);
		else
			throw new IllegalDuplicationException(t.getId());
	}
	
	/**
	 * Remove task from the user's task list
	 * @param task	Task to remove
	 * @effect Task t is removed from the task list
	 */
	public void removeTask(Task t)
	{
		this.tasks.remove(t);
	}
	
	/**
	 * Remove task based on id
	 * @param id of the task you want to remove
	 * @effect If a task t with description is found remove it
	 */
	public void removeTask(String id)
	{
		for(Task t : this.tasks)
		{
			if(t.getId().equals(description))
			{
				this.tasks.remove(t);
				return;
			}
		}
	}
	
	/**
	 * Inspector too see if a user owns a certain task
	 * @param task	Task to inspect
	 * @return	true if the user owns the task, false otherwise
	 */
	public boolean ownsTask(Task t)
	{
		return this.tasks.contains(t);
	}
	
	/**
	 * A list of Tasks property of the User
	 */
	private List<Task> tasks;
	
	
	/***************************************************************************
	 * 						User Type
	 ***************************************************************************/
	
	public UserTypeInterface getUserType()
	{
		return usertype.getInterface();
	}
	
	/** user type instance */
	private final UserType usertype;
	
	
	/***************************************************************************
	 * 						Java object interface
	 ***************************************************************************/
	
	/**
	 * @see Object#equals(Object)
	 */
	@Override
	public boolean equals(Object obj)
	{
		if(obj.getClass() == getClass())
		{
			if(((User) obj).getId().equals(this.getId()))
				return true;
		}
		return false;
	}
	
	/**
	 * @see Object#toString()
	 */
	@Override
	public String toString()
	{
		return getDescription();
	}

	@Override
	public String getRoleId() {
		return getUserType().getId();
	}
}
